package state;/*=============================================================*/

/* This is the state.State class in the state.State pattern. This class has 3 subclasses:
/* state.NoTransactionFeeState,state.TransactionFeeState and state.OverDrawnState.
/*=============================================================*/

import context.BankContext;

public abstract class State {
    private String acctNumber;
    protected double balance = 0;
    protected String state;
    protected static final String NOFEESTATE = "NoTransFeeState";
    protected static final String FEESTATE = "TransFeeState";
    protected static final String OVERDRAWNSTATE = "state.OverDrawnState";
    protected static final String TAXSTATE = "state.TaxState";
    protected static final String ERRORSTATE = "ErrorState";

    protected State stateObj;
    protected BankContext context;

    public void changeState() {
        balance = context.getBalance();
        if (balance < 0 && balance >= BankContext.OVERDRAW_LIMIT)
            state = OVERDRAWNSTATE;
        else if (balance >= BankContext.MIN_BALANCE && balance <= BankContext.TAX_BALANCE)
            state = NOFEESTATE;
        else if (balance >= 0 && balance < BankContext.MIN_BALANCE)
            state = FEESTATE;
        else if (balance >= BankContext.TAX_BALANCE) {
            state = TAXSTATE;
        } else {
            state = ERRORSTATE;
        }
        passStateObjToContext();
    }

    public void passStateObjToContext() {
        switch (state) {
        case OVERDRAWNSTATE:
            stateObj = new OverDrawnState();
            break;
        case NOFEESTATE:
            stateObj = new NoTransactionFeeState();
            break;
        case FEESTATE:
            stateObj = new TransactionFeeState();
            break;
        }
        context.setStateObj(stateObj);
    }

    public String getAcctNum() {
        return acctNumber;
    }

    public String getState() {
        return state;
    }

    public void setContext(BankContext context) {
        this.context = context;
    }

    public abstract void deposit(double amount);

    public abstract void withdraw(double amount);

    public abstract boolean isOverDrawnLimitReached();
}
